#include "llt.h"

#include <stdio.h>

#include <bsp_psram.h>

#define HSPI_BUFFER_SIZE     ((uint32_t)0x8000)
#define HSPI_WRITE_READ_ADDR ((uint32_t)0x0050)
#define HSPI_BASE_ADDR       ((uint32_t)0xA0000000)

static uint8_t tx_buf[HSPI_BUFFER_SIZE];
static uint8_t rx_buf[HSPI_BUFFER_SIZE];

static void __fill_buffer(uint8_t *pBuffer, uint32_t uwBufferLenght, uint32_t uwOffset)
{
    uint32_t tmpIndex = 0;

    /* Put in global buffer different values */
    for (tmpIndex = 0; tmpIndex < uwBufferLenght; tmpIndex++) {
        pBuffer[tmpIndex] = tmpIndex + uwOffset;
    }
}

static uint8_t __cmp_buffer(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength)
{
    while (BufferLength--) {
        if (*pBuffer1 != *pBuffer2) {
            return 1;
        }
        pBuffer1++;
        pBuffer2++;
    }
    return 0;
}

static void test_psram_demo(void **state)
{
    int ret;

    hal_mtd_t *mtd = hal_mtd_open("psram");
    assert_true(mtd != NULL);

    /* Fill the buffer to write */
    __fill_buffer(tx_buf, HSPI_BUFFER_SIZE, 0);

    ret = hal_mtd_write(mtd, HSPI_WRITE_READ_ADDR, HSPI_BUFFER_SIZE, (uint8_t *)tx_buf);
    assert_int_equal(0, ret);

    ret = hal_mtd_read(mtd, HSPI_WRITE_READ_ADDR, HSPI_BUFFER_SIZE, (uint8_t *)rx_buf);
    assert_int_equal(0, ret);

    ret = __cmp_buffer(tx_buf, rx_buf, HSPI_BUFFER_SIZE);
    assert_int_equal(0, ret);

    ret = hal_mtd_ioctl(mtd, PSRAM_CMD_MEMORY_MAPPED, 1);
    assert_int_equal(0, ret);

    ret = 0;
    __IO uint8_t *data_ptr = (__IO uint8_t *)(PSRAM_BASE_ADDR + HSPI_WRITE_READ_ADDR);
    uint32_t index;
    for (index = 0; index < HSPI_BUFFER_SIZE; index++, data_ptr++) {
        if (*data_ptr != tx_buf[index]) {
            ret = -1;
            break;
        }
    }
    assert_int_equal(0, ret);
}

/** test entry */

void test_psram(struct tester_case *caser)
{
    UnitTest tests[] = {
        unit_test(test_psram_demo),
    };

    caser->stats->totals = sizeof(tests) / sizeof(tests[0]);
    caser->stats->fails = run_tests(tests);
}

TESTER_CASE_DEF("test_psram", test_psram, NULL, NULL, 0);
